home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 8 / FM Towns Free Software Collection 8.iso / t_os / diskdup / diskdup.c < prev    next >
Text File  |  1994-06-01  |  25KB  |  1,033 lines

  1. /********************************************************************
  2.  *                                                                    *
  3.  *                            DISKDUP                            *
  4.  *                                                                    *
  5.  *                        オンメモリ型 DISKCOPY                        *
  6.  *                                                                    *
  7.  *                            diskdup.exp                                *
  8.  *                                                                    *
  9.  *                            for FM-TOWNS                            *
  10.  *                                                                    *
  11.  *            Copyright (c) ちにゃと & Tymic 1992. 1993.        *
  12.  *                                                                    *
  13.  *                            メイン ソース                            *
  14.  *                                                                    *
  15.  ********************************************************************/
  16.  
  17. #define    __PRGMAIN__                /* ファイル ID */
  18.  
  19.  
  20. /********************************************************************
  21.     インクルードファイル
  22. *********************************************************************/
  23.  
  24. /* HI-C ライブラリ ヘッダー */
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <conio.h>
  29. #include <dos.h>
  30.  
  31. /* T-BIOS C ライブラリ ヘッダー */
  32. #include <fmcfrb.h>
  33.  
  34. /* ソース ヘッダー */
  35. #include "diskdup.h"
  36. #include "ddupgui.h"
  37. #include "option.h"
  38.  
  39.  
  40. /********************************************************************
  41.     変数
  42. *********************************************************************/
  43.  
  44. char Title1[] = "DiskDup Ver "VER;
  45. char Title2[] = "Copyright (C) ちにゃと&TYMIC 1992.1993.";
  46.  
  47. static char *HelpMsg[] = {
  48.     "パラメ-タ-は先頭に - か / をつけます",
  49.     "大文字でも小文字でも構いません",
  50.     "-S -s 読み込んだディスクの内容のデ-タファイルを作成します",
  51.     "-L -l  デ-タファイルを読み込んでデュプリケ-トをします",
  52.     "-F -f  フォ-マットを行いながらデュプリケ-トします",
  53.     "-D -d  フォ-マットをせずにデュプリケ-トします",
  54.     "-I -i  エラ-時以外に選択/確認を行いません",
  55.     "-H -h -?  ヘルプメッセ-ジを表示します",
  56.     "ファイル名  デ-タファイル名を指定します ドライブ名パス名も含みます",
  57.     "例1  -F -I  フォ-マットをします。又選択/確認を行いません",
  58.     "例2  -S  MAOUDX_A.DSK",
  59.     " デ-タファイルを指定されたファイル名で作成します",
  60. };
  61. #define HELPMSG_MAX        sizeof( HelpMsg ) / sizeof( char* )
  62.  
  63. static char InMstAMsg[] = "マスターディスクをAドライブにセットして下さい";
  64. static char InCpyAMsg[] = "コピーディスクをAドライブにセットして下さい";
  65. static char InCpyBMsg[] = "コピーディスクをBドライブにセットして下さい";
  66. static char FormProcMsg[] = "フォーマットをしながらコピーを行います";
  67. static char EndMsg[] = "終了します";
  68.  
  69. char *ErrMsgTbl[] = {            /* エラー メッセージ テーブル */
  70.     "",
  71.     "モード設定エラーが発生しました",
  72.     "読み込みエラーが発生しました",
  73.     "書き込みエラーが発生しました",
  74.     "ドライブエラーが発生しました",
  75.     "未対応のディスクです",
  76.     "ドライブの準備が出来ていません",
  77.     "書き込み禁止のためコピー出来ません",
  78.     "フォーマットでエラーが発生しました",
  79. };
  80.  
  81. static char *DiskTypeMsgTbl[] = {    /* ディスク タイプ メッセージ テーブル */
  82.     "",
  83.     "1・2M 2HD 読み込み中",
  84.     "720k 2DD 読み込み中",
  85.     "640k 2DD 読み込み中",
  86.     "1・2M 2HC 読み込み中",
  87. };
  88.  
  89. static uint ChkMode1Tbl[] = {    /* セクタ ID 読み込み用 mode1 データ テーブル */
  90.     0x0003,                        /* MFM 2HD 1024 */
  91.     0x0012,                        /* MFM 2DD  512 */
  92.     0x0080,                        /*  FM 2HD  128 */
  93.     0x0090,                        /*  FM 2DD  128 */
  94. };
  95. #define ChkMode1Tbl_Size        sizeof( ChkMode1Tbl ) / sizeof( uint )
  96.  
  97. static FORMPARA  PreAmbl[] = {    /* プレ アンブル 圧縮 データ */
  98.     0x004e, 80,                    /* GAP0 */
  99.     0x0000, 12,                    /* SYNC */
  100.     0x00f6, 3,                    /* INDEX MARK 1 */
  101.     0x00fc, 1,                    /* INDEX MARK 2 */
  102.     0x004e, 50,                    /* GAP1 */
  103. };
  104. #define PreAmblCnt                sizeof( PreAmbl ) / sizeof( FORMPARA )
  105.  
  106. static FORMPARA  PosAmbl[] = {    /* ポスト アンブル 圧縮 データ */
  107.     0x004e, 600,                /* GAP4 */
  108. };
  109. #define PosAmblCnt                sizeof( PosAmbl ) / sizeof( FORMPARA )
  110.  
  111. static FORMPARA  SecData1024[] = {    /* 1024 セクタ 圧縮 データ */
  112.     0x0000, 12,                    /* SYNC */
  113.     0x00f5, 3,                    /* AM1_1 */
  114.     0x00fe, 1,                    /* AM1_2 */
  115.     0x0000, 1,                    /* ID TRACK NUMBER */
  116.     0x0000, 1,                    /* ID SIDE NUMBER */
  117.     0x0000, 1,                    /* ID SECTOR NUMBER */
  118.     0x0003, 1,                    /* ID SECTOR LENGTH */
  119.     0x00f7, 1,                    /* CRC */
  120.     0x00fe, 1,                    /* CRC */
  121.     0x004e, 22,                    /* GAP2 */
  122.     0x0000, 12,                    /* SYNC */
  123.     0x00f5, 3,                    /* AM2_1 */
  124.     0x00fb, 1,                    /* AM2_2 */
  125.     0x00e5, 1024,                /* DATA */
  126.     0x00f7, 1,                    /* CRC */
  127.     0x00fe, 1,                    /* CRC */
  128.     0x004e, 116,                /* GAP3 */
  129. };
  130. #define SecData1024Cnt            sizeof( SecData1024 ) / sizeof( FORMPARA )
  131.  
  132. static FORMPARA  SecData512[] = {    /* 512 セクタ 圧縮 データ */
  133.     0x0000, 12,                    /* SYNC */
  134.     0x00f5, 3,                    /* AM1_1 */
  135.     0x00fe, 1,                    /* AM1_2 */
  136.     0x0000, 1,                    /* ID TRACK NUMBER */
  137.     0x0000, 1,                    /* ID SIDE NUMBER */
  138.     0x0000, 1,                    /* ID SECTOR NUMBER */
  139.     0x0002, 1,                    /* ID SECTOR LENGTH */
  140.     0x00f7, 1,                    /* CRC */
  141.     0x00fe, 1,                    /* CRC */
  142.     0x004e, 22,                    /* GAP2 */
  143.     0x0000, 12,                    /* SYNC */
  144.     0x00f5, 3,                    /* AM2_1 */
  145.     0x00fb, 1,                    /* AM2_2 */
  146.     0x00e5, 512,                /* DATA */
  147.     0x00f7, 1,                    /* CRC */
  148.     0x00fe, 1,                    /* CRC */
  149.     0x004e, 116,                /* GAP3 */
  150. };
  151.  
  152. static int FormatFlg = TRUE;        /* フォーマット 実行 フラグ */
  153. static char *DiskData;                /* ディスク 読み込み バッファ ポインタ */
  154. static char FormDataBuf[1024*12];    /* フォーマット データ バッファ */
  155. static int disktype = 0;            /* ディスク タイプ */
  156.  
  157. int option = 0;                        /* オプション データ */
  158.  
  159.  
  160. /************************************************************************
  161. 【メイン処理】
  162.  
  163.         概要    メイン 関数
  164.         用法    無し
  165.         引数    int        argc
  166.                 char    **argv
  167.         戻り値    無し
  168.         注意    メモリ アロケート 後の プロセス 脱出は PrgExit1 関数を使用
  169. ************************************************************************/
  170.  
  171. void main( int argc, char *argv[] )
  172. {
  173.     union REGS        regs;
  174.     struct SREGS    sregs;
  175.     int                tmpi;
  176.  
  177.     /* GUI 初期設定 及び タイトル 表示 */
  178.     setscreen();
  179.     putworkbox();
  180.  
  181.     /* forRBIOS 常駐 チェック */
  182.     if ( FRB_getstatus() != 0 ) {
  183.         flagerr = 1;
  184.         strcpy( str, "forRBIOSが組み込まれていません" );
  185.         putmessage();
  186.         ready();
  187.         flagerr = 0;
  188.         PrgExit2();
  189.     }
  190.  
  191.     /* 共用 メモリ 容量 チェック */
  192.     _segread( &sregs );
  193.     regs.x.ax = 0x250d;
  194.     _int86x( 0x21, ®s, ®s, &sregs );
  195.     if ( regs.x.cx < sizeof( FormDataBuf ) ) {
  196.         flagerr = 1;
  197.         strcpy( str, "ごめんなさいリアルメモリ不足です" );
  198.         putmessage();
  199.         ready();
  200.         flagerr = 0;
  201.         PrgExit2();
  202.     }
  203.  
  204.     /* メモリ アロケ-ション */
  205.     if ( ( DiskData = (char *)malloc( DISKSIZE ) ) == NULL ) {
  206.         flagerr = 1;
  207.         strcpy( str, "ごめんなさいメモリ不足です" );
  208.         putmessage();
  209.         ready();
  210.         flagerr = 0;
  211.         PrgExit2();
  212.     }
  213.  
  214.     /* オプション 解析 */
  215.     option = optionset( argc, argv );
  216.  
  217.     if ( option == -1 ) {
  218.         flagerr = 1;
  219.         strcpy( str, "オプションが違います" );
  220.         putmessage();
  221.         ready();
  222.         option = -2;
  223.     }
  224.  
  225.     if ( ( option & 3 ) == 3 ) {
  226.         flagerr = 1;
  227.         strcpy( str, "デ-タファイルの読み込みと作成が同時に指定されました" );
  228.         putmessage();
  229.         ready();
  230.         PrgExit1();
  231.     }
  232.  
  233.     if ( option == -2 ) {
  234.         flagerr = 1;
  235.         for ( tmpi = 0; tmpi < HELPMSG_MAX; tmpi++ ) {
  236.             strcpy( str, HelpMsg[tmpi] );
  237.             putmessage();
  238.             ready();
  239.         }
  240.         PrgExit1();
  241.     }
  242.  
  243. /* debug *******************************
  244.     sprinf( str, "flagld = %d", flagld );
  245.     putmessage();
  246.     ready();
  247.  
  248.     sprintf( str, "flagsv = %d", flagsv );
  249.     putmessage();
  250.     ready();
  251.  
  252.     sprintf( str, "flaggofmt = %d", flaggofmt );
  253.     putmessage();
  254.     ready();
  255.  
  256.     sprintf( str, "flagunfmt = %d", flagunfmt );
  257.     putmessage();
  258.     ready();
  259.  
  260.     sprintf( str, "flagipt = %d", flagipt );
  261.     putmessage();
  262.     ready();
  263. /***************************************/
  264.  
  265.     /* コピー プログラム スタート */
  266.     CopyPrgMain();
  267.  
  268.     /* 処理終了 */
  269.     PrgExit1();
  270. }
  271.  
  272. /************************************************************************
  273. 【プログラム終了処理】
  274.  
  275.         概要    プログラム を終了して DOS へ戻る。
  276.         用法    PrgExit?();
  277.         引数    無し
  278.         戻り値    無し
  279.         注意    メモリ アロケート ポインタ は DiskData を使用
  280. ************************************************************************/
  281.  
  282. void PrgExit1( void )
  283. {
  284.     /* 2HD 1.2M モード に設定 */
  285.     SetDiskDrvMode( FD0_DRVNO, TYPE_2HD_12 );
  286.     SetDiskDrvMode( FD1_DRVNO, TYPE_2HD_12 );
  287.  
  288.     /* メモリ 開放 */
  289.     free( DiskData );
  290.  
  291.     PrgExit2();
  292. }
  293.  
  294. void PrgExit2( void )
  295. {
  296.     /* プロセス 脱出 */
  297.     exit( 0 );
  298. }
  299.  
  300.  
  301. /************************************************************************
  302. 【コピープログラムメイン処理】
  303.  
  304.         概要    プロッピー ディスク の ディスク コピー を行う。
  305.         用法    CopyPrgMain();
  306.         引数    無し
  307.         戻り値    無し
  308.         注意    無し
  309. ************************************************************************/
  310.  
  311. void CopyPrgMain( void )
  312. {
  313.     uint    status;        /* ドライブ ステータス */
  314.     int        drvno;        /* コピー 先 デバイス 番号 */
  315.     int        i;            /* 切り替え sw */
  316.  
  317.     if ( option & 1 ) {
  318.         flagerr = 1;
  319.         strcpy( str, " デ-タファイルを読み込みんでデュプリします" );
  320.         putmessage();
  321.         flagerr = 0;
  322.         if ( select() == 1 ) {
  323.             flagerr = 1;
  324.             strcpy( str, EndMsg );
  325.             putmessage();
  326.             ready();
  327.             return;
  328.         }
  329.  
  330.         disktype = loaddata( DiskData );
  331.         if ( ( disktype > TYPE_NOT ) && ( disktype < TYPE_END ) ) {
  332.             flagerr = 1;
  333.             strcpy( str, " デ-タファイルを読み込みました" );
  334.             putmessage();
  335.             flagerr = 0;
  336.             ready();
  337.         }
  338.         else {
  339.             flagerr = 1;
  340.             strcpy( str, " デ-タファイルを読み込み出来ませんでした" );
  341.             putmessage();
  342.             ready();
  343.             flagerr = 0;
  344.             strcpy( str, EndMsg );
  345.             putmessage();
  346.             ready();
  347.             return;
  348.         }
  349.     }
  350.     else {
  351.         for ( ;; ) {
  352.             /* ディスク セット メッセージ 表示 */
  353.             flagerr = 1;
  354.             strcpy( str, InMstAMsg );
  355.             putmessage();
  356.             if ( select() == 1 ) {
  357.                 strcpy( str, EndMsg );
  358.                 putmessage();
  359.                 if ( select() == -1 ) {
  360.                     return;
  361.                 }
  362.                 continue;
  363.             }
  364.  
  365.             flagerr = 0;
  366.  
  367.             /* ステータス 読み込み */
  368.             DKB_rdstatus( FD0_DRVNO, &status );
  369.             if ( status & 0x01 ) {
  370.                 ErrMsgPutWord( ERRNOTDISK );    /* ドライブ ノット レディー */
  371.                 continue;
  372.             }
  373.  
  374.             /* フォーマット タイプ チェック */
  375.             disktype = ChkFormatType( FD0_DRVNO );
  376.             if ( disktype == NG ) {
  377.                 ErrMsgPutWord( ERRDISKSET );        /* ディスク 設定 エラー */
  378.                 continue;
  379.             }
  380.             if ( disktype == TYPE_NOT ) {
  381.                 ErrMsgPutWord( ERRDISKTYPE );        /* 未対応 ディスク エラー */
  382.                 continue;
  383.             }
  384.  
  385.             /* モード 設定 */
  386.             if ( SetDiskDrvMode( FD0_DRVNO, disktype ) != 0 ) {
  387.                 ErrMsgPutWord( ERRMODESET );        /* モード セット エラー */
  388.                 continue;
  389.             }
  390.  
  391.             /* フォーマット タイプ 表示 */
  392.             clrmessage();
  393.             flagerr = 1;
  394.             strcpy( str, DiskTypeMsgTbl[disktype] );
  395.             putmessage();
  396.             flagerr = 0;
  397.             /* マスタ- ディスク 読み込み */
  398.             if ( ReadDiskAll( FD0_DRVNO, DiskData, disktype ) == 0 ) {
  399.                 break;    
  400.             }
  401.         }
  402.     }
  403.  
  404.     /* ディスク コピー */
  405.     if ( option & 2 ) {
  406.         flagerr = 1;
  407.         strcpy( str, " デ-タファイルを作成します" );
  408.         putmessage();
  409.         flagerr = 0;
  410.  
  411.         if ( select() == 1 ) {
  412.             flagerr = 1;
  413.             strcpy( str, EndMsg );
  414.             putmessage();
  415.             flagerr = 0;
  416.             ready();
  417.             return;
  418.         }
  419.         if ( savedata( DiskData, disktype ) == 0 ) {
  420.             flagerr = 1;
  421.             strcpy( str, " デ-タファイルを作成しました" );
  422.             putmessage();
  423.             flagerr = 0;
  424.             ready();
  425.             strcpy( str, EndMsg );
  426.             putmessage();
  427.             ready();
  428.         }
  429.         else {
  430.             flagerr = 1;
  431.             strcpy( str, " デ-タファイルの作成に失敗しました" );
  432.             putmessage();
  433.             flagerr = 0;
  434.             strcpy( str, EndMsg );
  435.             putmessage();
  436.             ready();
  437.         }
  438.         return ;
  439.     }
  440.     else {
  441.         if ( option & 1 )
  442.             drvno = FD0_DRVNO;    /* A ドライブ 設定 */
  443.         else
  444.             drvno = FD1_DRVNO;    /* B ドライブ 設定 */
  445.  
  446.         for ( ;; ) {
  447.             /* ディスク セット メッセージ 表示 */
  448.             strcpy( str, (drvno == FD0_DRVNO ? InCpyAMsg : InCpyBMsg) );
  449.             putmessage();
  450.             if ( select() == 1 ) {
  451.                 flagerr = 1;
  452.                 strcpy( str, EndMsg );
  453.                 putmessage();
  454.                 if ( select() == -1 ) {
  455.                     return;
  456.                 }
  457.                 continue;
  458.             }
  459.  
  460.             flagerr = 0;
  461.  
  462.             /* シリンダ 0 シ-ク & リセット */
  463.             if ( DKB_restore( drvno ) != 0 ) {
  464.                 ErrMsgPutWord( ERRNOTDISK );    /* ドライブ ノット レディー */
  465.                 flagerr = 1;
  466.                 continue;
  467.             }
  468.  
  469.             /* モード 設定 */
  470.             if ( SetDiskDrvMode( drvno, disktype ) != 0 ) {
  471.                 ErrMsgPutWord( ERRMODESET );    /* モード セット エラー */
  472.                 flagerr = 1;
  473.                 continue;
  474.             }
  475.  
  476.             if ( option & 8 ) {
  477.                 if ( option & 4 )
  478.                     i = 0;
  479.                 else
  480.                     i = 2;
  481.             }
  482.             else {
  483.                 if ( option & 4 )
  484.                     i = 1;
  485.                 else
  486.                     i = 0;
  487.             }
  488.  
  489.             switch ( i ) {
  490.                 case 0:
  491.                     /* フォーマット 実行確認表示 */
  492.                     strcpy( str, FormProcMsg );
  493.                     putmessage();
  494.                     if ( select() != 1 ) {
  495.                         FormatFlg = TRUE;        /* フォーマット 実行 */
  496.                         clrmessage();
  497.                         flagerr = 1;
  498.                         strcpy( str, "フォーマット&コピー中" );
  499.                         putmessage();
  500.                         flagerr = 0;
  501.                         break;
  502.                     }
  503.                     else
  504.                         /* case 1: へ*/
  505.  
  506.                 case 1:
  507.                     FormatFlg = FALSE;        /* フォーマット スキップ */
  508.                     clrmessage();
  509.                     flagerr = 1;
  510.                     strcpy( str, "コピー中" );
  511.                     putmessage();
  512.                     flagerr = 0;
  513.                     break;
  514.  
  515.                 case 2:
  516.                 default:
  517.                     FormatFlg = TRUE;        /* フォーマット 実行 */
  518.                     clrmessage();
  519.                     flagerr = 1;
  520.                     strcpy( str, "フォーマット&コピー中" );
  521.                     putmessage();
  522.                     flagerr = 0;
  523.                     break;
  524.             }
  525.  
  526.             /* ディスク 書き込み */
  527.             if ( WriteDiskAll( drvno, DiskData, disktype ) != 0 ) {
  528.                 flagerr = 1;
  529.                 continue;
  530.             }
  531.  
  532.             /* A ←→ B 変換 */
  533.             drvno = ( drvno == FD0_DRVNO ? FD1_DRVNO : FD0_DRVNO );
  534.         }
  535.     }
  536. }
  537.  
  538.  
  539. /************************************************************************
  540. 【ディスクモード設定】
  541.  
  542.         概要    ディスク ドライブ モード の設定を行う。
  543.         用法    SetDiskDrvMode( devno, sw );
  544.         引数    int        devno            : デバイス 番号
  545.                 int        sw                : TYPE_2HD_12
  546.                                         : TYPE_2DD_720
  547.                                         : TYPE_2DD_640
  548.                                         : TYPE_2HC_12
  549.         戻り値    int        0x0000            : 正常終了
  550.                         0x0002            : デバイス 番号 エラー
  551.                         0x8???            : ハード エラー
  552.                         NG                : その他の エラー
  553.         注意    無し
  554. ************************************************************************/
  555.  
  556. int SetDiskDrvMode( int devno, int sw )
  557. {
  558.     uint    mode1,        /* モード 1 */
  559.             mode2;        /* モード 2 */
  560.  
  561.     /* モ-ド 設定 */
  562.     switch ( sw ) {
  563.         case TYPE_2HD_12:        /* 2HD 1.2M */
  564.             mode1 =    MODE1_12;    /* MFM 2HD 1024 */
  565.             mode2 = MODE2_12;    /* 2 ヘッド 8 セクタ */
  566.             break;
  567.  
  568.         case TYPE_2DD_720:        /* 2DD 720K */
  569.             mode1 =    MODE1_720;    /* MFM 2DD 512 */
  570.             mode2 = MODE2_720;    /* 2 ヘッド 9 セクタ */
  571.             break;
  572.  
  573.         case TYPE_2DD_640:        /* 2DD 640K */
  574.             mode1 =    MODE1_640;    /* MFM 2DD 512 */
  575.             mode2 = MODE2_640;    /* 2 ヘッド 8 セクタ */
  576.             break;
  577.  
  578.         case TYPE_2HC_12:        /* 2HC 1.2M */
  579.             mode1 =    MODE1_12C;    /* MFM 2HD 512 */
  580.             mode2 = MODE2_12C;    /* 2 ヘッド 15 セクタ */
  581.             break;
  582.  
  583.         default:
  584.             return NG;
  585.     }
  586.  
  587.     return DKB_setmode( devno, mode1, mode2 );
  588. }
  589.  
  590.  
  591. /************************************************************************
  592. 【ディスク読み込み】
  593.  
  594.         概要    ディスク の 全 トラック (シリンダ) 分の 読み込みを行う。
  595.         用法    ReadDiskAll( devno, buf, sw );
  596.         引数    int        devno            : デバイス 番号
  597.                 char    *buf            : 読み込み バッファ ポインタ
  598.                 int        sw                : TYPE_2HD_12
  599.                                         : TYPE_2DD_720
  600.                                         : TYPE_2DD_640
  601.                                         : TYPE_2HC_12
  602.         戻り値    int        0x0000            : 正常終了
  603.                         0x0002            : デバイス 番号 エラー
  604.                         0x8???            : ハード エラー
  605.                         NG                : その他の エラー
  606.         注意    無し
  607. ************************************************************************/
  608.  
  609. int ReadDiskAll( int devno, char *buf, int sw )
  610. {
  611.     int        cylno,            /* 読み込み シリンダ 番号 */
  612.             headno,            /* 読み込み ヘッド 番号 */
  613.             seccnt,            /* 読み込み セクタ 数 */
  614.             secnum,            /* 残り セクタ 数 */
  615.             maxcylinder,    /* シリンダ 最大数 */
  616.             sectorlen,        /* セクタ 長 */
  617.             retry,            /* エラー リトライ カウンタ */
  618.             ret;            /* 戻り値 */
  619.     uint    offset = 0;        /* 読み込み ポインタ オフセット */
  620.  
  621.     /* セクタ 数, セクタ レングス, シリンダ 数, 設定 */
  622.     switch ( sw ) {
  623.         case TYPE_2HD_12:        /* 2HD 1.2M */
  624.             seccnt = MAXSEC_12;
  625.             maxcylinder = MAXCYL_2HD;
  626.             sectorlen = SECLEN1024;
  627.             break;
  628.  
  629.         case TYPE_2DD_720:        /* 2DD 720K */
  630.             seccnt = MAXSEC_720;
  631.             maxcylinder = MAXCYL_2DD;
  632.             sectorlen = SECLEN512;
  633.             break;
  634.  
  635.         case TYPE_2DD_640:        /* 2DD 640K */
  636.             seccnt = MAXSEC_640;
  637.             maxcylinder = MAXCYL_2DD;
  638.             sectorlen = SECLEN512;
  639.             break;
  640.  
  641.         case TYPE_2HC_12:        /* 2HC 1.2M */
  642.             seccnt = MAXSEC_12C;
  643.             maxcylinder = MAXCYL_2HC;
  644.             sectorlen = SECLEN512;
  645.             break;
  646.  
  647.         default:
  648.             return NG;
  649.     }
  650.  
  651.     for ( cylno = 0; cylno < maxcylinder; cylno++ ) {
  652.         retry = 0;
  653.         for ( headno = 0; headno < MAXHEAD; ) {
  654.             /* ディスク データ 読み込み */
  655.             if ( ( ret = DKB_read( devno, cylno, headno, 1,
  656.                                 seccnt, buf + offset, &secnum ) ) != 0 ) {
  657.                 if ( retry < RETRYMAX ) {        /* エラー リトライ */
  658.                     retry++;
  659.                     continue;
  660.                 }
  661.                 else {
  662.                     ErrMsgPutWord( ERRDISKREAD );    /* ディスク リード エラー */
  663.                     return ret;
  664.                 }
  665.             }
  666.             else {
  667.                 headno++;
  668.                 offset += sectorlen * seccnt;
  669.                 retry = 0;
  670.             }
  671.         }
  672.     }
  673.  
  674.     return 0;
  675. }
  676.  
  677.  
  678. /************************************************************************
  679. 【ディスク書き込み】
  680.  
  681.         概要    ディスク の 全 トラック (シリンダ) 分の 書き込みを行う。
  682.         用法    WriteDiskAll( devno, buf, sw );
  683.         引数    int        devno            : デバイス 番号
  684.                 char    *buf            : 書き込み バッファ ポインタ
  685.                 int        sw                : TYPE_2HD_12
  686.                                         : TYPE_2DD_720
  687.                                         : TYPE_2DD_640
  688.                                         : TYPE_2HC_12
  689.         戻り値    int        0x0000            : 正常終了
  690.                         0x0002            : デバイス 番号 エラー
  691.                         0x8???            : ハード エラー
  692.                         NG                : その他の エラー
  693.         注意    無し
  694. ************************************************************************/
  695.  
  696. int WriteDiskAll( int devno, char *buf, int sw )
  697. {
  698.     int        cylno,            /* 書き込み シリンダ 番号 */
  699.             headno,            /* 書き込み ヘッド 番号 */
  700.             seccnt,            /* 書き込み セクタ 数 */
  701.             secnum,            /* 残り セクタ 数 */
  702.             maxcylinder,    /* シリンダ 最大数 */
  703.             sectorlen,        /* セクタ 長 */
  704.             retry,            /* エラー リトライ カウンタ */
  705.             ret;            /* 戻り値 */
  706.     uint    offset = 0;        /* 書き込み ポインタ オフセット */
  707.  
  708.     /* セクタ 数, セクタ レングス, シリンダ 数, 設定 */
  709.     switch ( sw ) {
  710.         case TYPE_2HD_12:        /* 2HD 1.2M */
  711.             seccnt = MAXSEC_12;
  712.             maxcylinder = MAXCYL_2HD;
  713.             sectorlen = SECLEN1024;
  714.             break;
  715.  
  716.         case TYPE_2DD_720:        /* 2DD 720K */
  717.             seccnt = MAXSEC_720;
  718.             maxcylinder = MAXCYL_2DD;
  719.             sectorlen = SECLEN512;
  720.             break;
  721.  
  722.         case TYPE_2DD_640:        /* 2DD 640K */
  723.             seccnt = MAXSEC_640;
  724.             maxcylinder = MAXCYL_2DD;
  725.             sectorlen = SECLEN512;
  726.             break;
  727.  
  728.         case TYPE_2HC_12:        /* 2HC 1.2M */
  729.             seccnt = MAXSEC_12C;
  730.             maxcylinder = MAXCYL_2HC;
  731.             sectorlen = SECLEN512;
  732.             break;
  733.  
  734.         default:
  735.             return NG;
  736.     }
  737.  
  738.     for ( cylno = 0; cylno < maxcylinder; cylno++ ) {
  739.         retry = 0;
  740.         for ( headno = 0; headno < MAXHEAD; ) {
  741.             if ( FormatFlg == TRUE ) {
  742.                 /* フォーマット データ 作成 */
  743.                 MakeFormData( cylno, headno, sw );
  744.                 /* トラック フォーマット */
  745.                 if ( ( ret = TrackFormat( devno, cylno, headno ) ) != 0 ) {
  746.                     if ( ret & 0x02 ) {
  747.                         ErrMsgPutWord( ERRPROTECT );    /* 書き込み禁止 */
  748.                         return ret;
  749.                     }
  750.                     else if ( ret & 0x01 ) {
  751.                         ErrMsgPutWord( ERRNOTDISK );    /* ドライブ ノット レディー */
  752.                         return ret;
  753.                     }
  754.                     else {
  755.                         if ( retry < RETRYMAX ) {        /* エラー リトライ */
  756.                             retry++;
  757.                             continue;
  758.                         }
  759.                         else {
  760.                             ErrMsgPutWord( ERRFORMAT );        /* フォ-マット エラ- */
  761.                             return ret;
  762.                         }
  763.                     }
  764.                 }
  765.             }
  766.  
  767.             /* データ ディスク 書き込み */
  768.             if ( ( ret = DKB_write( devno, cylno, headno, 1,
  769.                             seccnt, buf + offset, &secnum ) ) != 0 ) {
  770.                 if ( ret & 0x02 ) {
  771.                     ErrMsgPutWord( ERRPROTECT );    /* 書き込み禁止 */
  772.                     return ret;
  773.                 }
  774.                 else if ( ret & 0x01 ) {
  775.                     ErrMsgPutWord( ERRNOTDISK );    /* ドライブ ノット レディー */
  776.                     return ret;
  777.                 }
  778.                 else {
  779.                     if ( retry < RETRYMAX ) {        /* エラー リトライ */
  780.                         retry++;
  781.                         continue;
  782.                     }
  783.                     else {
  784.                         ErrMsgPutWord( ERRDISKWRITE );    /* ディスク ライト エラー */
  785.                         return ret;
  786.                     }
  787.                 }
  788.             }
  789.             else {
  790.                 headno++;
  791.                 offset += sectorlen * seccnt;
  792.                 retry = 0;
  793.              }
  794.         }
  795.     }
  796.  
  797.     return 0;
  798. }
  799.  
  800.  
  801. /************************************************************************
  802. 【1トラックフォーマット】
  803.  
  804.         概要    ディスク の 1 トラック (シリンダ) 分の フォーマット を行う。
  805.         用法    TrackFormat( devno, cylno, headno );
  806.         引数    int        devno            : デバイス 番号
  807.                 int        cylno            : シリンダ 番号
  808.                 int        headno            : ヘッド 番号
  809.         戻り値    int        0x0000            : 正常終了
  810.                         0x0002            : デバイス 番号 エラー
  811.                         0x8???            : ハード エラー
  812.         注意    フォ-マット データ は FormDataBuf を使用する
  813. ************************************************************************/
  814.  
  815. int TrackFormat( int devno, int cylno, int headno )
  816. {
  817.     union REGS        regs;
  818.     struct SREGS    sregs;
  819.     ushort            dsdata;
  820.     IntParaBlk        parablk;
  821.  
  822. /* debug *******************************
  823.     return (DKB_format( devno, cylno, headno, FormDataBuf ));
  824. /***************************************/
  825.  
  826.     /* セグメント データ 読み込み */
  827.     _segread( &sregs );
  828.     dsdata = sregs.ds;
  829.  
  830.     /* 共用 バッファ アドレス 取得 DOS-Extender ファンクション */
  831.     regs.x.ax = 0x250d;
  832.     _int86x( 0x21, ®s, ®s, &sregs );
  833.  
  834.     /* フォーマット データ バッファ から 共用 バッファ へ データ コピー */
  835.     _movedata( (uint)dsdata, (uint)FormDataBuf,
  836.                     (uint)sregs.es, regs.x.dx, sizeof(FormDataBuf) );
  837.  
  838.     /* フォーマット ファンクション を DOS-Extender を介して発行 */
  839.     parablk.intno = 0x93;                        /* 割り込み番号 */
  840.     parablk.reax = (uint)(0x0a00 | devno);        /* BIOS ファンクション 番号 & デバイス 番号 */
  841.     regs.x.cx = (uint)cylno;                    /* シリンダ 番号 */
  842.     parablk.redx = (uint)(headno << 8);            /* ヘッド 番号 */
  843.     parablk.rds = (ushort)(regs.x.bx >> 16);    /* 共用 バッファ リアル セグメント */
  844.     regs.x.di = regs.x.bx & 0xffff;                /* 共用 バッファ リアル オフセット */
  845.     parablk.res = 0;                            /* 未使用 */
  846.     parablk.rfs = 0;
  847.     parablk.rgs = 0;
  848.  
  849.     regs.x.ax = 0x2511;                            /* リアル モード 割り込み発行 */
  850.     regs.x.dx = (uint)¶blk;                    /* パラメータ ブロック オフセット */
  851.     sregs.ds = sregs.ss;                        /* パラメータ ブロック セグメント */
  852.     _intdosx( ®s, ®s, &sregs );            /* int 21h ax = 2511h 実行 */
  853.  
  854.     if ( regs.h.ah <= 0x02 )
  855.         return (int)(regs.h.ah);
  856.     else
  857.         return (int)( (regs.x.cx | 0x8000) & 0xffff );
  858. }
  859.  
  860.  
  861. /************************************************************************
  862. 【フォーマットデータ作成】
  863.  
  864.         概要    1 トラック (シリンダ) 分の フォーマット データ 作成を行う。
  865.         用法    MakeFormData( cylno, headno, sw );
  866.         引数    int        cylno            : シリンダ 番号
  867.                 int        headno            : ヘッド 番号
  868.                 int        sw                : TYPE_2HD_12
  869.                                         : TYPE_2DD_720
  870.                                         : TYPE_2DD_640
  871.                                         : TYPE_2HC_12
  872.         戻り値    無し
  873.         注意    フォ-マット データ は FormDataBuf を使用する
  874. ************************************************************************/
  875.  
  876. void MakeFormData( int cylno, int headno, int sw )
  877. {
  878.     int            i;
  879.     int            secnum,
  880.                 secmax;
  881.     char        *p;
  882.     FORMPARA    *secdata;
  883.  
  884.     /* 作成 セクタ 数 & セクタ 圧縮 データ 設定 */
  885.     switch ( sw ) {
  886.         case TYPE_2DD_640:        /* 2DD 640K */
  887.             secmax = MAXSEC_640;
  888.             secdata = SecData512;
  889.             break;
  890.  
  891.         case TYPE_2DD_720:        /* 2DD 720K */
  892.             secmax = MAXSEC_720;
  893.             secdata = SecData512;
  894.             break;
  895.  
  896.         case TYPE_2HC_12:        /* 2HC 1.2M */
  897.             secmax = MAXSEC_12C;
  898.             secdata = SecData512;
  899.             break;
  900.  
  901.         case TYPE_2HD_12:        /* 2HD 1.2M */
  902.         default:
  903.             secmax = MAXSEC_12;
  904.             secdata = SecData1024;
  905.             break;
  906.     }
  907.  
  908.     p = FormDataBuf;
  909.  
  910.     /* プレ アンブル データ 展開 */
  911.     for ( i = 0; i < PreAmblCnt; i++ ) {
  912.         memset( p, PreAmbl[i].fdata, PreAmbl[i].cnt );
  913.         p += PreAmbl[i].cnt;
  914.     }
  915.  
  916.     /* セクタ データ 展開 */
  917.     secdata[3].fdata = cylno;    /* ID TRACK NUMBER */
  918.     secdata[4].fdata = headno;    /* ID SIDE NUMBER */
  919.     for ( secnum = 0; secnum < secmax; secnum++ ) {
  920.         secdata[5].fdata = secnum + 1;    /* ID SECTOR NUMBER */
  921.         for ( i = 0; i < SecData1024Cnt; i++ ) {
  922.             memset( p, secdata[i].fdata, secdata[i].cnt );
  923.             p += secdata[i].cnt;
  924.         }
  925.     }
  926.  
  927.     /* ポスト アンブル データ 展開 */
  928.     memset( p, PosAmbl[0].fdata, PosAmbl[0].cnt );
  929. }
  930.  
  931.  
  932. /************************************************************************
  933. 【フォーマットタイプチェック】
  934.  
  935.         概要    ディスク の フォ-マット タイプ を調べる。
  936.         用法    ChkFormatType( devno );
  937.         引数    int        devno            : デバイス 番号
  938.         戻り値    int        TYPE_NOT        : 未対応 ディスク
  939.                         TYPE_2HD_12        : 1.2M 2HD
  940.                         TYPE_2DD_720    : 720K 2DD
  941.                         TYPE_2DD_640    : 640K 2DD
  942.                         TYPE_2HC_12        : 1.2M 2HC
  943.                         NG                : ディスク エラー
  944.         注意    シリンダ 2, ヘッド 0 の フォーマット チェック
  945.                 セクタ ID を読みだして タイプ を決定する
  946. ************************************************************************/
  947.  
  948. int ChkFormatType( int devno )
  949. {
  950.     DKB_SEC        secid[30];
  951.     uint        mode1tmp,
  952.                 mode2tmp,
  953.                 cnt;
  954.     int            flg,
  955.                 ret;
  956.  
  957.     /* シリンダ 0 シ-ク & リセット */
  958.     if ( DKB_restore( devno ) != 0 )
  959.         return NG;
  960.  
  961.     /* シリンダ 2 シ-ク */
  962.     if ( DKB_seek( devno, 2 ) != 0 )
  963.         return NG;
  964.  
  965.     flg = FALSE;    /* フラグ クリア */
  966.     for ( cnt = 0; cnt < ChkMode1Tbl_Size; cnt++ ) {
  967.         /* ドライブ モード 仮設定 */
  968.         DKB_setmode( devno, ChkMode1Tbl[cnt], 0x0208 );
  969.  
  970.         /* セクタ ID 取り出し */
  971.         if ( ( ret = DKB_rdsecid( devno, 2, 0, &secid[0] ) ) == 0 ) {
  972.             flg = TRUE;
  973.             break;        /* 正常終了なら ループ 脱出 */
  974.         }
  975.         else if ( ret & 0x0003 ) {
  976.             return NG;    /* ドライブ 異常終了 */
  977.         }
  978.     }
  979.  
  980.     /* 処理 フラグ チェック */
  981.     if ( flg == FALSE )
  982.         return NG;        /* セクタ ID 無し */
  983.  
  984.     /* ドライブ モード 取り出し */
  985.     DKB_rdmode( devno, &mode1tmp, &mode2tmp );
  986.  
  987.     /* 30 セクタ 分の ID を 読む */
  988.     for ( cnt = 0; cnt < 30; cnt++ ) {
  989.         if ( DKB_rdsecid( devno, 2, 0, &secid[cnt] ) != 0 )
  990.             return NG;
  991.     }
  992.  
  993.     /* セクタ 数の チェック */
  994.     flg = FALSE;    /* フラグ クリア */
  995.     for ( cnt = 1; cnt < 30; cnt++ ) {
  996.         if ( secid[0].secno == secid[cnt].secno ) {
  997.             flg = TRUE;
  998.             break;        /* 正常終了なら ループ 脱出 */
  999.         }
  1000.     }
  1001.  
  1002.     /* 処理 フラグ チェック */
  1003.     if ( flg == FALSE )
  1004.         return NG;        /* セクタ 異常 */
  1005.  
  1006.     /* mode 1 作成 */
  1007.     mode1tmp &= 0xfc;
  1008.     mode1tmp |= (uint)(secid[0].seccnt);
  1009.  
  1010.     /* mode 2 作成 */
  1011.     mode2tmp &= 0xff00;
  1012.     mode2tmp |= cnt;
  1013.  
  1014.     /* フォーマット タイプ 選別 */
  1015.     if ( mode1tmp == MODE1_12 && mode2tmp == MODE2_12 ) {
  1016.         return TYPE_2HD_12;        /* 1.2M 2HD */
  1017.     }
  1018.     else if ( mode1tmp == MODE1_720 && mode2tmp == MODE2_720 ) {
  1019.         return TYPE_2DD_720;    /* 720K 2DD */
  1020.     }
  1021.     else if ( mode1tmp == MODE1_640 && mode2tmp == MODE2_640 ) {
  1022.         return TYPE_2DD_640;    /* 640K 2DD */
  1023.     }
  1024.     else if ( mode1tmp == MODE1_12C && mode2tmp == MODE2_12C ) {
  1025.         return TYPE_2HC_12;        /* 1.2M 2HC */
  1026.     }
  1027.  
  1028.     return TYPE_NOT;            /* 未対応 ディスク */
  1029. }
  1030.  
  1031.  
  1032. /* end of file */
  1033.